package hell.satan.droidbdf.fragment;

import android.os.Bundle;
import android.support.annotation.CallSuper;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.RecyclerView.LayoutManager;
import android.support.v7.widget.RecyclerView.ViewHolder;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import java.lang.ref.WeakReference;

import hell.satan.droidbdf.R;
import hell.satan.droidbdf.base.BaseFragment;

/**
 * 对RecyclerView进行包装的Fragement
 * Fragement wrapper for RecyclerView
 *
 * @author Cerberus
 */
@SuppressWarnings("unused")
public abstract class RecyclerFragment extends BaseFragment implements SwipeRefreshLayout.OnRefreshListener {
    protected RecyclerAdapter mRecyclerAdapter;

    protected SwipeRefreshLayout mSrlRefresh;
    protected RecyclerView mRccRecycler;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle state) {
        return inflater.inflate(R.layout.fragment_recycler, container, false);
    }

    @CallSuper
    @Override
    public void onViewCreated(View view, @Nullable Bundle state) {
        super.onViewCreated(view, state);
        mSrlRefresh = (SwipeRefreshLayout) view.findViewById(R.id.refresh);
        mSrlRefresh.setEnabled(getRefreshEnabled());
        mSrlRefresh.setOnRefreshListener(this);

        mRccRecycler = (RecyclerView) view.findViewById(R.id.recycler);
        mRccRecycler.setLayoutManager(getLayoutManager());
        mRecyclerAdapter = new RecyclerAdapter(this);
        mRccRecycler.setAdapter(mRecyclerAdapter);
    }

    /**
     * 设置是否启用下拉刷新
     * Sets whether to enable SwipeRefreshLayout
     *
     * @return SwipeRefreshLayout的默认状态 Default state of SwipeRefreshLayout
     */
    protected boolean getRefreshEnabled() {
        return mSrlRefresh.isEnabled();
    }

    /**
     * 设置RecyclerView的LayoutManager
     * Set LayoutManager of RecyclerView
     *
     * @return RecyclerView的默认LayoutManager Default LayoutManager of RecyclerView
     */
    @NonNull
    protected LayoutManager getLayoutManager() {
        return mRccRecycler.getLayoutManager();
    }

    /**
     * 当RecyclerView的条目被按下时调用此方法
     * Called when the item of RecyclerView is pressed
     *
     * @param recycler 触发事件的RecyclerView
     *                 The RecyclerView which trigger click event
     * @param view     触发事件的条目
     *                 The item which trigger click event
     * @param position 触发事件的位置索引
     *                 The position of item which trigger click event
     * @param id       触发事件的ID
     *                 The id of item which trigger click event
     */
    protected void onItemClick(RecyclerView recycler, View view, int position, long id) {
    }

    /**
     * 当RecyclerView的条目被长按时调用此方法
     * Called when the item of RecyclerView is long pressed
     *
     * @param recycler 触发事件的RecyclerView
     *                 The RecyclerView which trigger click event
     * @param view     触发事件的条目
     *                 The item which trigger click event
     * @param position 触发事件的位置索引
     *                 The position of item which trigger click event
     * @param id       触发事件的ID
     *                 The id of item which trigger click event
     * @return 返回True表示事件已经被处理过了，否则返回False
     * true if the callback consumed the long click, false otherwise.
     */
    protected boolean onItemLongClick(RecyclerView recycler, View view, int position, long id) {
        return false;
    }

    /** @see SwipeRefreshLayout.OnRefreshListener#onRefresh() */
    @Override
    public void onRefresh() {
    }

    /** @see RecyclerView.Adapter#getItemCount() */
    protected abstract int getItemCount();

    /** @see RecyclerView.Adapter#onCreateViewHolder(ViewGroup, int) */
    protected abstract ViewHolder onCreateViewHolder(LayoutInflater inflater, ViewGroup parent, int type);

    /** @see RecyclerView.Adapter#onBindViewHolder(ViewHolder, int) */
    protected abstract void onBindViewHolder(ViewHolder holder, int position);

    /** @see RecyclerView.Adapter#onViewRecycled(ViewHolder) */
    protected void onViewRecycled(ViewHolder holder) {
    }

    /** @see RecyclerView.Adapter#getItemViewType(int) */
    protected int getItemViewType(int position) {
        return 0;
    }

    /** @see RecyclerView.Adapter#getItemId(int) */
    protected long getItemId(int position) {
        return RecyclerView.NO_ID;
    }

    /** @see RecyclerView.Adapter#notifyDataSetChanged() */
    public void notifyDataSetChanged() {
        mRecyclerAdapter.notifyDataSetChanged();
    }

    protected static class RecyclerAdapter extends RecyclerView.Adapter {
        private WeakReference<RecyclerFragment> mReference;

        RecyclerAdapter(RecyclerFragment fragment) {
            mReference = new WeakReference<>(fragment);
        }

        @Override
        public int getItemCount() {
            RecyclerFragment fragment = mReference.get();
            return fragment == null ? 0 : fragment.getItemCount();
        }

        @Override
        public ViewHolder onCreateViewHolder(ViewGroup parent, int type) {
            final RecyclerFragment fragment = mReference.get();
            if (fragment != null) {
                LayoutInflater inflater = LayoutInflater.from(fragment.getContext());
                final RecyclerView.ViewHolder holder = fragment.onCreateViewHolder(inflater, parent, type);
                holder.itemView.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        fragment.onItemClick(fragment.mRccRecycler, view,
                                holder.getLayoutPosition(), holder.getItemId());
                    }
                });
                holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
                    @Override
                    public boolean onLongClick(View view) {
                        return fragment.onItemLongClick(fragment.mRccRecycler, view,
                                holder.getLayoutPosition(), holder.getItemId());
                    }
                });
                return holder;
            }
            return null;
        }

        @Override
        public void onBindViewHolder(ViewHolder holder, int position) {
            RecyclerFragment fragment = mReference.get();
            if (fragment != null) fragment.onBindViewHolder(holder, position);
        }

        @Override
        public void onViewRecycled(ViewHolder holder) {
            RecyclerFragment fragment = mReference.get();
            if (fragment != null) fragment.onViewRecycled(holder);
        }

        @Override
        public int getItemViewType(int position) {
            RecyclerFragment fragment = mReference.get();
            return fragment == null ? 0 : fragment.getItemViewType(position);
        }

        @Override
        public long getItemId(int position) {
            RecyclerFragment fragment = mReference.get();
            return fragment == null ? RecyclerView.NO_ID : fragment.getItemId(position);
        }
    }
}
